package com.caption.core.local;

import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: 用户线程变量
 * @author: 码农
 * @date: 2021-12-24 23:12:30
 */
@Slf4j
public final class UserThreadLocal {

    private static final String USER_KEY = "userId";
    private static final String USER_INFO = "userInfo";
    private static final String REQUEST_URI = "requestUri";
    private static final String APP_CONFIG = "appConfig";
    /**
     * 使用阿里TransmittableThreadLocal 能够父子线程共享用户线程变量，注意在拦截器后一定要执行remove()方法，否则会造成内存泄露。
     */
    private static ThreadLocal<Map<String, Object>> localUserThreadLocal = new TransmittableThreadLocal<>();

    public static Map<String, Object> getLocalMap() {
        Map<String, Object> map = localUserThreadLocal.get();
        if (map == null) {
            map = new ConcurrentHashMap<>(16);
            localUserThreadLocal.set(map);
        }
        return map;
    }

    public static void setRequestUri(String requestUri) {
        if (StringUtils.isNotBlank(requestUri)) {
            getLocalMap().put(REQUEST_URI, requestUri);
        } else {
            log.info("requestUri为空");
        }
    }

    public static String getRequestUri() {
        Object value = getLocalMap().get(REQUEST_URI);
        if (value == null) {
            return null;
        }
        return (String) value;
    }

    public static void setUserKey(String userKey) {
        getLocalMap().put(USER_KEY, userKey);
    }

    public static String getUserKey() {
        Object value = getLocalMap().get(USER_KEY);
        if (value == null) {
            return null;
        }
        return (String) value;
    }

    /**
     * 保存用户信息
     *
     * @param userInfo
     */
    public static void setUserInfo(LocalUser userInfo) {
        getLocalMap().put(USER_INFO, userInfo);
    }

    public static LocalUser getUserInfo() {
        Object value = getLocalMap().get(USER_INFO);
        if (value == null) {
            throw new RuntimeException("未找到用户信息");
        }
        return (LocalUser) value;
    }

    /**
     * 保存应用配置信息
     *
     * @param appConfig
     */
    public static void setAppConfig(AppConfig appConfig) {
        getLocalMap().put(APP_CONFIG, appConfig);
    }

    public static AppConfig getAppConfig() {
        Object value = getLocalMap().get(APP_CONFIG);
        if (value == null) {
            throw new RuntimeException("未找到app配置信息");
        }
        return (AppConfig) value;
    }

    public static void remove() {
        if (localUserThreadLocal != null) {
            localUserThreadLocal.remove();
        }

    }

    public static String getToken() {
        return getUserInfo().getToken();
    }


}
